<template>
  <div class="form-page-container">
    <!-- 表单标题 -->
    <div class="form-head">
      <div class="head-button" @click="backEvent">
        <div class="back-button-svg">
          <svg-icon icon-class="back"></svg-icon>
        </div>
        <div class="back-button-text">返回</div>
      </div>
      <div class="head-title">{{ config.title }}</div>
    </div>

    <div class="form-toolbar">
      <div class="toolbar-last toolbar-last-next" @click="lastNextRow('last')">
        <el-tooltip class="item" effect="dark" content="上一条" placement="bottom">
          <div class="toolbar-last-svg">
            <svg-icon icon-class="last"></svg-icon>
          </div>
        </el-tooltip>
      </div>
      <div class="toolbar-next toolbar-last-next" @click="lastNextRow('next')">
        <el-tooltip effect="dark" content="下一条" placement="bottom">
          <div class="toolbar-next-svg">
            <svg-icon icon-class="next"></svg-icon>
          </div>
        </el-tooltip>
      </div>
      <div
        class="toolbar-custom-btn"
        v-for="(item, index) in config.toolBarBtns"
        :key="index"
      >
        <div v-if="!item.more">
          <el-button
            v-if="
              (!item.showCondition || item.showCondition(currentRowData)) &&
              $btnPermission.verify(item.permission)
            "
            :type="item.type"
            @click="customBtnClick(item.click, item.confirm)"
          >
            <div v-if="item.iconName" class="custom-btn-svg">
              <svg-icon
                :icon-class="item.iconName"
                :style="`color: ${item.iconColor}};`"
                :size="1.2"
              ></svg-icon>
            </div>
            <div :class="item.iconName ? 'custom-btn-name' : ''">
              {{ item.name }}
            </div>
          </el-button>
        </div>
        <div class="toolbar-custom-more" v-if="item.more">
          <el-dropdown>
            <span class="el-dropdown-link">
              <svg-icon icon-class="btn-more"></svg-icon>
              {{ item.name }}
              <i class="el-icon-arrow-down el-icon--right"></i>
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item
                v-for="(moreItem, moreIndex) in item.more"
                :key="moreIndex"
              >
                <div
                  class="more-menu-btn"
                  @click="customBtnClick(moreItem.click, moreItem.confirm)"
                  v-if="
                    (!moreItem.showCondition || moreItem.showCondition(currentRowData)) &&
                    $btnPermission.verify(moreItem.permission)
                  "
                >
                  <div
                    v-if="moreItem.iconName"
                    class="menu-btn-svg"
                    :class="moreItem.iconName ? 'more-menu-margin' : ''"
                  >
                    <svg-icon
                      :icon-class="moreItem.iconName"
                      :style="`color: ${moreItem.iconColor}};`"
                    ></svg-icon>
                  </div>
                  <div class="menu-btn-name">
                    {{ moreItem.name }}
                  </div>
                </div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
      </div>
    </div>

    <!-- 表单信息 -->
    <div
      class="form-page-menu"
      :class="!config.collapse || config.collapse.length <= 0 ? 'form-page-menu-top' : ''"
    >
      <el-form
        v-if="!config.collapse || config.collapse.length <= 0"
        :model="form"
        ref="menuForm"
        :rules="rules"
        label-width="100px"
      >
        <el-row
          :gutter="24"
          v-for="(rowItem, rowIndex) in currentFormItems"
          :key="rowIndex"
        >
          <el-col
            v-for="(colItem, colIndex) in rowItem"
            :key="colIndex"
            :span="colItem.col"
          >
            <el-form-item :label="`${colItem.title}:`" :prop="colItem.name">
              <div v-if="!colItem.input || colItem.input === 'text'">
                <el-input
                  v-model="form[colItem.name]"
                  :disabled="formDisabled || colItem.disabled"
                  :placeholder="colItem.placeholder"
                  @change="formInfoChange(config.formChange)"
                ></el-input>
              </div>
              <div v-else-if="colItem.input === 'textarea'">
                <el-input
                  type="textarea"
                  v-model="form[colItem.name]"
                  :disabled="formDisabled || colItem.disabled"
                  :placeholder="colItem.placeholder"
                  @change="formInfoChange(config.formChange)"
                ></el-input>
              </div>
              <div v-else-if="colItem.input === 'select'">
                <div v-if="!colItem.tree">
                  <el-select
                    v-model="form[colItem.name]"
                    :placeholder="colItem.placeholder"
                    style="width: 100%"
                    :disabled="formDisabled || colItem.disabled"
                    @change="formInfoChange(config.formChange)"
                  >
                    <el-option
                      v-for="(item, index) in colItem.options"
                      :key="Number(index)"
                      :label="item"
                      :value="Number(index)"
                    >
                    </el-option>
                  </el-select>
                </div>
                <div v-if="colItem.tree">
                  <SelectTree
                    :modelValue.sync="form[colItem.name]"
                    :defaultValue="colItem.defaultValue"
                    :dataFun="colItem.treeDataFun"
                    :disabled="formDisabled || colItem.disabled"
                  />
                </div>
              </div>
              <div v-else-if="colItem.input === 'image'">
                <UploadImageFile :limit="6" :uploadValue.sync="form[colItem.name]" />
              </div>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <el-form
        v-if="config.collapse && config.collapse.length > 0"
        :model="form"
        ref="menuForm"
        :rules="rules"
        label-width="100px"
      >
        <el-collapse class="form-page-collpase" :value="collapseItemOpen">
          <el-collapse-item
            v-for="(collapseItem, collapseIndex) in collapseFormItems"
            :key="collapseIndex"
            :name="collapseItem.name"
          >
            <template slot="title">
              <div class="collapse-item-title">
                {{ collapseItem.title }}
              </div>
              <div class="collapse-item-svg" v-if="collapseItem.iconName">
                <svg-icon
                  :icon-class="collapseItem.iconName"
                  :style="`color: ${collapseItem.iconColor}};`"
                ></svg-icon>
              </div>
            </template>
            <el-row
              :gutter="24"
              v-for="(rowItem, rowIndex) in collapseItem.formItems"
              :key="rowIndex"
            >
              <el-col
                v-for="(colItem, colIndex) in rowItem"
                :key="colIndex"
                :span="colItem.col"
              >
                <el-form-item :label="`${colItem.title}:`" :prop="colItem.name">
                  <div v-if="!colItem.input || colItem.input === 'text'">
                    <el-input
                      v-model="form[colItem.name]"
                      :disabled="formDisabled || colItem.disabled"
                      :placeholder="colItem.placeholder"
                      @change="formInfoChange(config.formChange)"
                    ></el-input>
                  </div>
                  <div v-else-if="colItem.input === 'textarea'">
                    <el-input
                      type="textarea"
                      v-model="form[colItem.name]"
                      :disabled="formDisabled || colItem.disabled"
                      :placeholder="colItem.placeholder"
                      @change="formInfoChange(config.formChange)"
                    ></el-input>
                  </div>
                  <div v-else-if="colItem.input === 'select'">
                    <div v-if="!colItem.tree">
                      <el-select
                        v-model="form[colItem.name]"
                        :placeholder="colItem.placeholder"
                        style="width: 100%"
                        :disabled="formDisabled || colItem.disabled"
                        @change="formInfoChange(config.formChange)"
                      >
                        <el-option
                          v-for="(item, index) in colItem.options"
                          :key="Number(index)"
                          :label="item"
                          :value="Number(index)"
                        >
                        </el-option>
                      </el-select>
                    </div>
                    <div v-if="colItem.tree">
                      <SelectTree
                        :modelValue.sync="form[colItem.name]"
                        :defaultValue="colItem.defaultValue"
                        :dataFun="colItem.treeDataFun"
                        :disabled="formDisabled || colItem.disabled"
                      />
                    </div>
                  </div>
                </el-form-item>
              </el-col>
            </el-row>
          </el-collapse-item>
        </el-collapse>
      </el-form>
    </div>
  </div>
</template>
<script>
import UploadImageFile from "@/components/UploadImageFile/index.vue";
import SelectTree from "@/components/SelectTree/index.vue";

export default {
  name: "FormPage",
  components: {
    UploadImageFile,
    SelectTree,
  },
  props: {
    config: {
      type: Object,
      default: () => {},
    },
    currentId: {
      type: [Number, String],
      default: () => 0,
    },
    tableIds: {
      type: Array,
      default: () => [],
    },
    rowData: {
      type: Object,
      default: () => {},
    },
  },
  watch: {
    form: {
      handler(val) {
        console.log(val);
      },
    },
  },
  data() {
    return {
      currentRow: {
        id: null,
        index: 0,
      },
      a: 4,
      form: {},
      rules: {},
    };
  },
  computed: {
    lastNextTableIds: {
      get() {
        return this.loadLastNextTableIds();
      },
    },

    currentRowData: {
      get() {
        return this.rowData;
      },
    },

    currentFormItems: {
      get() {
        return this.config.formItems ? this.config.formItems : [];
      },
    },

    collapseFormItems: {
      get() {
        return this.config.collapse ? this.config.collapse : [];
      },
    },
    collapseItemOpen: {
      get() {
        return this.config.collapse
          ? this.config.collapse.filter((item) => item.isOpen).map((item) => item.name)
          : [];
      },
    },
    formDisabled: {
      get() {
        if (!this.config.disabledForm || typeof this.config.disabledForm !== "function") {
          return false;
        }
        return this.config.disabledForm(this.currentRowData);
      },
    },
  },
  created() {
    this.$nextTick(() => {
      setTimeout(async () => {
        await this.reloadFormPage();

        await this.loadLastNextTableIds();
      }, 200);

      setTimeout(() => {
        this.$refs.menuForm.clearValidate();
      }, 210);
    });
  },
  methods: {
    async getPageFormItems() {
      let formPageItems = [];
      for (let i = 0; i < this.currentFormItems.length; i++) {
        formPageItems.push(this.currentFormItems[i]);
      }
      for (let i = 0; i < this.collapseFormItems.length; i++) {
        formPageItems.push(this.collapseFormItems[i]);
      }
      return formPageItems;
    },

    async initFormData() {
      if (this.$commonUtil.isNotEmptyObject(this.currentRowData)) {
        this.form = { ...this.currentRowData };
      } else {
        let formatData = {};
        const pageFormItems = await this.getPageFormItems();
        for (let formItem in pageFormItems) {
          if (formItem.name) {
            formatData[formItem.name] = null;
          }
        }
        this.form = { ...formatData };
      }
    },

    async defaultValue() {
      await this.handleFormRules(await this.getPageFormItems());

      // 处理默认值
      if (!this.currentRowData || !this.currentRowData.id) {
        await this.handleFormDefaultValue(await this.getPageFormItems());
      }
    },

    handleFormRules(formItems) {
      let formRules = {};
      for (let i = 0; i < formItems.length; i++) {
        const items = formItems[i];
        for (let m = 0; m < items.length; m++) {
          if (items[m].rules) {
            formRules[items[m].name] = items[m].rules;
          }
        }
      }
      this.rules = formRules;
    },

    handleFormDefaultValue(formItems) {
      for (let i = 0; i < formItems.length; i++) {
        const items = formItems[i];
        for (let m = 0; m < items.length; m++) {
          if (
            items[m].defaultValue &&
            typeof (
              items[m].defaultValue === "string" || items[m].defaultValue === "Number"
            )
          ) {
            if (items[m].defaultValue && String(items[m].defaultValue).length > 0) {
              this.$set(this.form, items[m].name, items[m].defaultValue);
            }
          }
        }
      }
    },

    loadLastNextTableIds() {
      let lastNextIds = [];
      if (this.tableIds && this.tableIds.length > 0) {
        this.tableIds.forEach((item, index) => {
          lastNextIds.push({
            id: item,
            index: index,
          });
          if (Number(item) === this.currentId) {
            this.currentRow = { id: item, index: index };
          }
        });
      }
      return lastNextIds;
    },
    // 返回事件
    backEvent() {
      this.$emit("backEvent");
    },

    // 上下一页
    lastNextRow(module) {
      if (!this.tableIds || this.tableIds.length <= 1) {
        this.$message.error("当前最后一条");
        return;
      }
      let currentRowIndex = this.currentRow.index;
      if (module === "last") {
        if (this.currentRow.index <= 0) {
          this.$message.error("当前第一条");
          return;
        }
        currentRowIndex = currentRowIndex - 1;
      }
      const formPageTableIds = this.lastNextTableIds;
      if (module === "next") {
        currentRowIndex = currentRowIndex + 1;
        if (currentRowIndex >= formPageTableIds.length) {
          this.$message.error("当前最后一条");
          return;
        }
      }
      const currentRowId = formPageTableIds.filter(
        (item) => item.index === currentRowIndex
      )[0].id;
      this.currentRow.index = currentRowIndex;
      this.currentRow.id = currentRowId;
      const loading = this.$loading({
        lock: true,
        text: module === "last" ? "上一条" : "下一条",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      });
      this.$emit("update:currentId", currentRowId);
      this.$emit("lastNextRow", currentRowId, loading);
    },

    // 自定义按钮事件
    async customBtnClick(callback, confirm) {
      if (!callback || typeof callback !== "function") {
        this.$message.error("按钮未绑定任何事件");
        return;
      }
      // 二次确认
      if (confirm) {
        this.$confirm(confirm.message, confirm.title, {
          confirmButtonText: "确定",
          cancelButtonText: "取消",
          type: "warning",
        })
          .then(async () => {
            await this.customCallback(callback);
          })
          .catch((e) => {
            console.log(e);
            this.$message({
              type: "info",
              message: "已取消操作",
            });
          });
      } else {
        await this.customCallback(callback);
      }
    },
    async customCallback(callback) {
      console.log(this.form);
      this.$refs.menuForm.validate(async (valid) => {
        if (valid) {
          const loading = this.$loading({
            lock: true,
            text: "正在操作中",
            spinner: "el-icon-loading",
            background: "rgba(0, 0, 0, 0.7)",
          });
          try {
            await callback(this.currentRow.id | this.currentId, this.form, this.$parent);
            loading.close();
          } catch (e) {
            loading.close();
          }
        }
      });
    },

    // 表单数据信息改变事件
    formInfoChange(callback) {
      if (!callback || typeof callback !== "function") {
        return;
      }
      callback(this.form);
    },

    // 重置表单
    reloadFormPage() {
      this.$nextTick(async () => {
        await this.initFormData();

        await this.defaultValue();
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.form-page-container {
  padding: 0px;
  margin: 0px;
  width: 100%;
  height: 100%;
  overflow: hidden;

  .form-head {
    width: 100%;
    height: 50px;
    position: relative;
    display: flex;
    justify-content: flex-start;

    .head-title {
      font-size: 20px;
      font-weight: bold;
      height: 35px;
      line-height: 40px;
      margin-left: 10px;
      color: rgb(0, 170, 239);
    }

    .head-button {
      width: 70px;
      height: 30px;
      display: flex;
      justify-content: center;
      line-height: 30px;
      background-color: #f0f0f0;
      margin-top: 5px;
      cursor: pointer;

      .back-button-svg {
        margin-right: 5px;
      }

      .back-button-text {
        font-weight: 400;
      }
    }

    .head-button:hover {
      background-color: rgb(224, 224, 224);
    }
  }

  .form-head::after {
    content: "";
    position: absolute;
    top: 40px;
    left: 0;
    width: 100%;
    height: 1px;
    background-color: rgb(0, 170, 239);
  }

  .form-toolbar {
    width: 100%;
    height: 60px;
    position: relative;
    display: flex;
    justify-content: flex-start;
    line-height: 40px;
    margin-top: 15px;

    .toolbar-last-next {
      text-align: center;
      width: 40px;
      height: 40px;
      background-color: #f0f0f0;
      cursor: pointer;
    }

    .toolbar-last-next:hover {
      background-color: rgb(224, 224, 224);
    }

    .toolbar-last {
      margin-right: 10px;
    }

    .toolbar-custom-btn {
      .el-button {
        margin-left: 15px;
        position: relative;

        .custom-btn-svg {
          position: absolute;
          left: 5px;
        }

        .custom-btn-name {
          margin-left: 5px;
        }
      }

      .toolbar-custom-more {
        background-color: #f0f0f0;
        padding-left: 5px;
        padding-right: 5px;
        width: 100px;
        text-align: center;

        .svg-icon {
          margin-right: 5px;
        }

        .el-dropdown-link {
          cursor: pointer;
          color: #132638;
        }

        .el-icon-arrow-down {
          font-size: 12px;
        }
      }
    }
  }

  .form-toolbar::after {
    content: "";
    position: absolute;
    top: 50px;
    left: 0;
    width: 100%;
    height: 3px;
    background-color: rgb(0, 170, 239);
  }

  .form-page-menu-top {
    margin-top: 10px;
  }

  .form-page-menu {
    width: 100%;

    .form-page-collpase {
      .collapse-item-title {
        font-weight: bold;
        font-size: 17px;
      }

      .collapse-item-svg {
        margin-left: 15px;
        margin-right: 15px;
      }
    }
    .el-collapse {
      border-top: none;

      ::v-deep .el-collapse-item__content {
        padding-bottom: 0px !important;
      }
    }
  }
}

.more-menu-btn {
  width: 100%;
  display: flex;
  justify-content: center;

  .more-menu-margin {
    margin-right: 5px;
  }
}

::v-deep .el-textarea__inner {
  color: black !important;
}

::v-deep .el-input__inner {
  color: black !important;
}
</style>
